
package rawengine.sound.OpenAL;

import static org.lwjgl.openal.AL10.*;
import org.lwjgl.util.WaveData;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


public class OpenALWave{
// static properties
  /** ArrayList of waves to be created. */
  private static HashMap<String, OpenALWave> genWaves = new HashMap<String, OpenALWave>();
  private static IntBuffer buffers = null;

// wave properties
  /** The path of the wave file. */
  private String path;
  /** The id or name of the wave file. */
  int id;

  /**
   * Load a wave file. Don't use this method directly. Use OpenALWave.create(String path) instead
   * to avoid multiple loading of one of the same wave file.
   *
   * @param path the file name of the wave file
   */
  private OpenALWave(String path){
    this.path = path;

    // add to list to load wave later
    genWaves.put(path, this);
  }

  /**
   * Use this method to load wave files.
   *
   * @param path path the file name of the wave file
   * @return the wave object
   */
  public static OpenALWave create(String path){
    Object obj = genWaves.get(path);
    if(obj != null)
      return (OpenALWave) obj;
    else
      return new OpenALWave(path);
  }

  /**
   * Generates all loaded waves.
   * Must be called before waves can be used with OpenAL.
   */
  @SuppressWarnings("rawtypes")
public static void alGenWaves(){
    // create buffer
	  if(buffers != null)
	  {
		 return;
	  }
	  buffers = OpenALUtils.createIntBuffer(genWaves.size());
	  //System.out.println(buffers.capacity());
	  alGenBuffers(buffers);
    
    
    OpenALUtils.checkError();

    Iterator it = genWaves.entrySet().iterator();

    int i = 0;
    while(it.hasNext())
    {
      OpenALWave openALWave = (OpenALWave) (((Map.Entry) it.next()).getValue());

      //load wave data
      System.out.println("Loading wave file: " + openALWave.path);
      File file = new File(openALWave.path);
      FileInputStream fs = null;
      if(file.exists())
      {
    	  try {
    			fs = new FileInputStream(file);
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
      }
     
	
      
      WaveData wavefile = WaveData.create(fs);
            
      openALWave.id = buffers.get(i);
      
      //copy to buffers
      alBufferData(
    		  openALWave.id,
              wavefile.format,
              wavefile.data,              
              wavefile.samplerate);
      OpenALUtils.checkError();

      //unload file again
      wavefile.dispose();

      i++;
    }
  }

  /**
   * Deletes all generatet buffers.
   */
  public static void alDeleteWaves(){
    if(buffers != null){
      alDeleteBuffers(buffers);
      buffers = null;
    }
  }

  public String toString(){
    return "File name: \"" + path + "\", ID: " + id;
  }
}
